home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / games / 111 / main.c < prev    next >
C/C++ Source or Header  |  1987-02-19  |  28KB  |  987 lines

  1. /*    main.c        */
  2. #include "header.h"
  3. #ifndef TOS
  4. #include <pwd.h>
  5. #endif
  6. static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
  7. int srcount=0;    /* line counter for showstr()    */
  8. int dropflag=0; /* if 1 then don't lookforobject() next round */
  9. int rmst=80;    /*    random monster creation counter        */
  10. int userid;        /* the players login user id number */
  11. char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */
  12. static char viewflag=0;
  13.     /*    if viewflag then we have done a 99 stay here and don't showcell in the main loop */
  14. char restorflag=0;    /* 1 means restore has been donestatic char cmdhelp[] = "\
  15.     */
  16. #ifdef TOS
  17. static char *cmdhelp[] = {
  18. "Cmd line format: larn [-slicnh] [-o<optsifle>] [-##]\n",
  19. "  -s   show the scoreboard\n",
  20. "  -l   show the logfile (wizard id only)\n",
  21. "  -i   show scoreboard with inventories of dead characters\n",
  22. "  -c   create new scoreboard (wizard id only)\n",
  23. "  -n   suppress welcome message on starting game\n",
  24. "  -##  specify level of difficulty (example: -5)\n",
  25. "  -h   print this help text\n",
  26. "  -o<optsfile>   specify larnopts filename to be used instead of larnopts\n"};
  27. #else
  28. static char cmdhelp[] = "\
  29. Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
  30.   -s   show the scoreboard\n\
  31.   -l   show the logfile (wizard id only)\n\
  32.   -i   show scoreboard with inventories of dead characters\n\
  33.   -c   create new scoreboard (wizard id only)\n\
  34.   -n   suppress welcome message on starting game\n\
  35.   -##  specify level of difficulty (example: -5)\n\
  36.   -h   print this help text\n\
  37.   ++   restore game from checkpoint file\n\
  38.   -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
  39. ";
  40. #endif
  41.  
  42. #ifdef VT100
  43. static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
  44.     "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
  45.     "vt341"  };
  46. #endif VT100
  47. /*
  48.     ************
  49.     MAIN PROGRAM
  50.     ************
  51.  */
  52. main(argc,argv)
  53.     int argc;
  54.     char **argv;
  55.     {
  56.     register int i,j;
  57.     int hard;
  58.     char *ptr=0,*ttype;
  59. #ifndef TOS
  60.     struct passwd *pwe,*getpwuid();
  61. #endif
  62. /*
  63.  *    first task is to identify the player
  64.  */
  65. #ifndef VT100
  66.     init_term();    /* setup the terminal (find out what type) for termcap */
  67. #endif VT100
  68. #ifndef TOS
  69.     if (((ptr = getlogin()) == 0) || (*ptr==0))    /* try to get login name */
  70.       if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
  71.         ptr = pwe->pw_name;
  72.       else
  73. #endif
  74.       if ((ptr = getenv("USER")) == 0)
  75.         if ((ptr = getenv("LOGNAME")) == 0)
  76.           {
  77. #ifdef TOS
  78.           noone: cputs("Can't find your logname.  Who Are You?\n");
  79. #else TOS
  80.           noone: write(2, "Can't find your logname.  Who Are You?\n",39);
  81. #endif TOS
  82.                   exit();
  83.           }
  84.     if (ptr==0) goto noone;
  85.     if (strlen(ptr)==0) goto noone;
  86. /*
  87.  *    second task is to prepare the pathnames the player will need
  88.  */
  89.     strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
  90.     strcpy(logname,ptr);    /* this will be overwritten with the players name */
  91. #ifdef TOS
  92.     if ((ptr = getenv("LARNDIR")) == 0) ptr = "";
  93.     strcpy(savefilename, ptr);
  94.     strcat(savefilename, "\Larn.sav");    /* save file name in home directory */
  95.     sprintf(optsfile, "%s\%s",ptr,LARNOPTS);
  96.     strcpy(scorefile,ptr);
  97.     strcpy(logfile,ptr);
  98.     strcpy(helpfile,ptr);
  99.     strcpy(larnlevels,ptr);
  100.     strcpy(fortfile,ptr);
  101.     strcpy(playerids,ptr);
  102. #else
  103.     if ((ptr = getenv("HOME")) == 0) ptr = ".";
  104. #ifdef SAVEINHOME
  105.     strcpy(savefilename, ptr);
  106.     strcat(savefilename, "/Larn.sav");    /* save file name in home directory */
  107. #else SAVEINHOME
  108.     strcat(savefilename,logname);    /* prepare savefile name */
  109.     strcat(savefilename,".sav");    /* prepare savefile name */
  110. #endif SAVEINHOME
  111.     sprintf(optsfile, "%s/%s",ptr,LARNOPTS);    /* the .larnopts filename */
  112. #endif
  113.     strcat(scorefile, SCORENAME);    /* the larn scoreboard filename */
  114.     strcat(logfile, LOGFNAME);        /* larn activity logging filename */
  115.     strcat(helpfile, HELPNAME);        /* the larn on-line help file */
  116.     strcat(larnlevels, LEVELSNAME);    /* the pre-made cave level data file */
  117.     strcat(fortfile, FORTSNAME);    /* the fortune data file name */
  118.     strcat(playerids, PLAYERIDS);    /* the playerid data file name */
  119. #ifndef NOHOLIDAYS
  120.     strcat(holifile, HOLIFILE);        /* the holiday data file name */
  121. #endif
  122. /*
  123.  *    now malloc the memory for the dungeon 
  124.  */
  125.     cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
  126.     if (cell == 0) died(-285);    /* malloc failure */
  127.     lpbuf    = malloc((5* BUFBIG)>>2);    /* output buffer */
  128.     inbuffer = malloc((5*MAXIBUF)>>2);    /* output buffer */
  129.     if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
  130.  
  131.     lcreat((char*)0);    newgame();        /*    set the initial clock  */ hard= -1;
  132. #ifdef VT100
  133. /*
  134.  *    check terminal type to avoid users who have not vt100 type terminals
  135.  */
  136.     ttype = getenv("TERM");
  137.     for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
  138.         if (strcmp(ttype,termtypes[i]) == 0) { j=0;  break; }
  139.     if (j)
  140.         {
  141.         lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
  142.         exit();
  143.         }
  144. #endif VT100
  145.  
  146. /*
  147.  *    now make scoreboard if it is not there (don't clear) 
  148.  */
  149.     if (access(scorefile,0) == -1) /* not there */
  150.         makeboard();
  151.  
  152. /*
  153.  *    now process the command line arguments 
  154.  */
  155.     for (i=1; i<argc; i++)
  156.         {
  157.         if (argv[i][0] == '-')
  158.           switch(tolower(argv[i][1]))
  159.             {
  160.             case 's': showscores();  exit();  /* show scoreboard   */
  161.  
  162.             case 'l': /* show log file     */
  163.                         diedlog();        exit();
  164.  
  165.             case 'i': showallscores();  exit();  /* show all scoreboard */
  166.  
  167.             case 'c':          /* anyone with password can create scoreboard */
  168.                       lprcat("Preparing to initialize the scoreboard.\n");
  169.                       if (getpassword() != 0)  /*make new scoreboard*/
  170.                             {
  171.                             makeboard(); lprc('\n'); showscores();
  172.                             }
  173.                       exit();
  174.  
  175.             case 'n':    /* no welcome msg    */ nowelcome=1; argv[i][0]=0; break;
  176.  
  177.             case '0': case '1': case '2': case '3': case '4': case '5':
  178.             case '6': case '7': case '8': case '9':    /* for hardness */
  179.                         sscanf(&argv[i][1],"%d",&hard);    
  180.                         break;
  181.  
  182.             case 'h':    /* print out command line arguments */
  183. #ifdef TOS
  184.                 {int i;
  185.                     for (i=0;i<9;i++)
  186.                         printf("%s",cmdhelp[i]);
  187.                         exit(0);
  188.                 }
  189. #else
  190.                         write(1,cmdhelp,sizeof(cmdhelp));  exit();
  191. #endif
  192.             case 'o':    /* specify a .larnopts filename */
  193.                         strncpy(optsfile,argv[i]+2,127);  break;
  194.  
  195.             default:    printf("Unknown option <%s>\n",argv[i]);  exit();
  196.             };
  197.  
  198. #ifndef TOS
  199.         if (argv[i][0] == '+')
  200.             {
  201.             clear();    restorflag = 1;
  202.             if (argv[i][1] == '+')
  203.                 {
  204.                 hitflag=1; restoregame(ckpfile); /* restore checkpointed game */
  205.                 }
  206.             i = argc;
  207.             }
  208. #endif
  209.         }
  210.     readopts();        /* read the options file if there is one */
  211. #ifdef TIMECHECK
  212. /*
  213.  *    this section of code checks to see if larn is allowed during working hours
  214.  */
  215.     if (dayplay==0)    /* check for not-during-daytime-hours */
  216.       if (playable())
  217.         {
  218.         write(2,"Sorry, Larn can not be played during working hours.\n",52);
  219.         exit();
  220.         }
  221. #endif TIMECHECK
  222.  
  223. #ifdef UIDSCORE
  224.     userid = geteuid();    /* obtain the user's effective id number */
  225. #else UIDSCORE
  226.     userid = getplid(logname);    /* obtain the players id number */
  227. #endif UIDSCORE
  228. #ifdef TOS
  229.     if (userid < 0) { cputs("Can't obtain playerid\n"); exit(); }
  230. #else
  231.     if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); }
  232. #endif
  233. #ifdef HIDEBYLINK
  234. /*
  235.  *    this section of code causes the program to look like something else to ps
  236.  */
  237.     if (strcmp(psname,argv[0])) /* if a different process name only */
  238.         {
  239.         if ((i=access(psname,1)) < 0)
  240.             {        /* link not there */
  241.             if (link(argv[0],psname)>=0)
  242.                 {
  243.                 argv[0] = psname;   execv(psname,argv);
  244.                 }
  245.             }
  246.         else 
  247.             unlink(psname);
  248.         }
  249.  
  250.     for (i=1; i<argc; i++)
  251.         {
  252.         szero(argv[i]);    /* zero the argument to avoid ps snooping */
  253.         }
  254. #endif HIDEBYLINK
  255.  
  256.     if (access(savefilename,0)==0)    /* restore game if need to */
  257.         {
  258.         clear();    restorflag = 1;
  259.         hitflag=1;    restoregame(savefilename);  /* restore last game    */
  260.         }
  261.     sigsetup();        /* trap all needed signals    */
  262.     sethard(hard);    /* set up the desired difficulty                */
  263.     setupvt100();    /*    setup the terminal special mode                */
  264.     if (c[HP]==0)    /* create new game */
  265.         {
  266.         makeplayer();    /*    make the character that will play            */
  267.         newcavelevel(0);/*    make the dungeon                             */
  268.         predostuff = 1;    /* tell signals that we are in the welcome screen */
  269.         if (nowelcome==0) welcome();     /* welcome the player to the game */
  270.         }
  271.     drawscreen();    /*    show the initial dungeon                    */
  272.     predostuff = 2;    /* tell the trap functions that they must do a showplayer()
  273.                         from here on */
  274.     /* nice(1);    /* games should be run niced */
  275.     yrepcount = hit2flag = 0;
  276.     while (1)
  277.         {
  278.         if (dropflag==0) lookforobject(); /* see if there is an object here    */
  279.             else dropflag=0; /* don't show it just dropped an item */
  280.         if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); }    /*    move the monsters        */
  281.         if (viewflag==0) showcell(playerx,playery); else viewflag=0;    /*    show stuff around player    */
  282.         if (hit3flag) flushall();
  283.         hitflag=hit3flag=0;    nomove=1;
  284.         bot_linex();    /* update bottom line */
  285.         while (nomove)
  286.             {
  287.             if (hit3flag) flushall();
  288.             nomove=0; parse();
  289.             }    /*    get commands and make moves    */
  290.         regen();            /*    regenerate hp and spells            */
  291.         if (c[TIMESTOP]==0)
  292.             if (--rmst <= 0)
  293.                 { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
  294.         }
  295.     }
  296.  
  297. /*
  298.     showstr()
  299.  
  300.     show character's inventory
  301.  */
  302. showstr()
  303.     {
  304.     register int i,number;
  305.     for (number=3, i=0; i<26; i++)
  306.         if (iven[i]) number++;    /* count items in inventory */
  307.     t_setup(number);    qshowstr();      t_endup(number);
  308.     }
  309.  
  310. qshowstr()
  311.     {
  312.     register int i,j,k,sigsav;
  313.     srcount=0;  sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  314.     if (c[GOLD]) { lprintf(".)   %d gold pieces",(long)c[GOLD]); srcount++; }
  315.     for (k=26; k>=0; k--)
  316.       if (iven[k])
  317.         {  for (i=22; i<84; i++)
  318.              for (j=0; j<=k; j++)  if (i==iven[j])  show3(j); k=0; }
  319.  
  320.     lprintf("\nElapsed time is %d.  You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
  321.     more();        nosignal=sigsav;
  322.     }
  323.  
  324. /*
  325.  *    subroutine to clear screen depending on # lines to display
  326.  */
  327. t_setup(count)
  328.     register int count;
  329.     {
  330.     if (count<20)  /* how do we clear the screen? */
  331.         {
  332.         cl_up(79,count);  cursor(1,1);
  333.         }
  334.     else
  335.         {
  336.         resetscroll(); clear();
  337.         }
  338.     }
  339.  
  340. /*
  341.  *    subroutine to restore normal display screen depending on t_setup()
  342.  */
  343. t_endup(count)
  344.     register int count;
  345.     {
  346.     if (count<18)  /* how did we clear the screen? */
  347.         draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
  348.     else
  349.         {
  350.         drawscreen(); setscroll();
  351.         }
  352.     }
  353.  
  354. /*
  355.     function to show the things player is wearing only
  356.  */
  357. showwear()
  358.     {
  359.     register int i,j,sigsav,count;
  360.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  361.     srcount=0;
  362.  
  363.      for (count=2,j=0; j<=26; j++)     /* count number of items we will display */
  364.        if (i=iven[j])
  365.         switch(i)
  366.             {
  367.             case OLEATHER:    case OPLATE:    case OCHAIN:
  368.             case ORING:        case OSTUDLEATHER:    case OSPLINT:
  369.             case OPLATEARMOR:    case OSSPLATE:    case OSHIELD:
  370.             count++;
  371.             };
  372.  
  373.     t_setup(count);
  374.  
  375.     for (i=22; i<84; i++)
  376.          for (j=0; j<=26; j++)
  377.            if (i==iven[j])
  378.             switch(i)
  379.                 {
  380.                 case OLEATHER:    case OPLATE:    case OCHAIN:
  381.                 case ORING:        case OSTUDLEATHER:    case OSPLINT:
  382.                 case OPLATEARMOR:    case OSSPLATE:    case OSHIELD:
  383.                 show3(j);
  384.                 };
  385.     more();        nosignal=sigsav;    t_endup(count);
  386.     }
  387.  
  388. /*
  389.     function to show the things player can wield only 
  390.  */
  391. showwield()
  392.     {
  393.     register int i,j,sigsav,count;
  394.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  395.     srcount=0;
  396.  
  397.      for (count=2,j=0; j<=26; j++)    /* count how many items */
  398.        if (i=iven[j])
  399.         switch(i)
  400.             {
  401.             case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
  402.             case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
  403.             case OSPIRITSCARAB:  case OCUBEofUNDEAD:
  404.             case OPOTION:   case OSCROLL:  break;
  405.             default:  count++;
  406.             };
  407.  
  408.     t_setup(count);
  409.  
  410.     for (i=22; i<84; i++)
  411.          for (j=0; j<=26; j++)
  412.            if (i==iven[j])
  413.             switch(i)
  414.                 {
  415.                 case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
  416.                 case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
  417.                 case OSPIRITSCARAB:  case OCUBEofUNDEAD:
  418.                 case OPOTION:   case OSCROLL:  break;
  419.                 default:  show3(j);
  420.                 };
  421.     more();        nosignal=sigsav;    t_endup(count);
  422.     }
  423.  
  424. /*
  425.  *    function to show the things player can read only
  426.  */
  427. showread()
  428.     {
  429.     register int i,j,sigsav,count;
  430.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  431.     srcount=0;
  432.  
  433.     for (count=2,j=0; j<=26; j++)
  434.         switch(iven[j])
  435.             {
  436.             case OBOOK:    case OSCROLL:    count++;
  437.             };
  438.     t_setup(count);
  439.  
  440.     for (i=22; i<84; i++)
  441.          for (j=0; j<=26; j++)
  442.            if (i==iven[j])
  443.             switch(i)
  444.                 {
  445.                 case OBOOK:    case OSCROLL:    show3(j);
  446.                 };
  447.     more();        nosignal=sigsav;    t_endup(count);
  448.     }
  449.  
  450. /*
  451.  *    function to show the things player can eat only
  452.  */
  453. showeat()
  454.     {
  455.     register int i,j,sigsav,count;
  456.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  457.     srcount=0;
  458.  
  459.     for (count=2,j=0; j<=26; j++)
  460.         switch(iven[j])
  461.             {
  462.             case OCOOKIE:    count++;
  463.             };
  464.     t_setup(count);
  465.  
  466.     for (i=22; i<84; i++)
  467.          for (j=0; j<=26; j++)
  468.            if (i==iven[j])
  469.             switch(i)
  470.                 {
  471.                 case OCOOKIE:    show3(j);
  472.                 };
  473.     more();        nosignal=sigsav;    t_endup(count);
  474.     }
  475.  
  476. /*
  477.     function to show the things player can quaff only
  478.  */
  479. showquaff()
  480.     {
  481.     register int i,j,sigsav,count;
  482.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  483.     srcount=0;
  484.  
  485.     for (count=2,j=0; j<=26; j++)
  486.         switch(iven[j])
  487.             {
  488.             case OPOTION:    count++;
  489.             };
  490.     t_setup(count);
  491.  
  492.     for (i=22; i<84; i++)
  493.          for (j=0; j<=26; j++)
  494.            if (i==iven[j])
  495.             switch(i)
  496.                 {
  497.                 case OPOTION:    show3(j);
  498.                 };
  499.     more();        nosignal=sigsav;        t_endup(count);
  500.     }
  501.  
  502. show1(idx,str2)
  503.     register int idx;
  504.     register char *str2[];
  505.     {
  506.     if (str2==0)  lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
  507.     else if (*str2[ivenarg[idx]]==0)  lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
  508.     else lprintf("\n%c)   %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
  509.     }
  510.  
  511. show3(index)
  512.     register int index;
  513.     {
  514.     switch(iven[index]) 
  515.         {
  516.         case OPOTION:    show1(index,potionname);  break;
  517.         case OSCROLL:    show1(index,scrollname);  break;
  518.  
  519.         case OLARNEYE:        case OBOOK:            case OSPIRITSCARAB:
  520.         case ODIAMOND:        case ORUBY:            case OCUBEofUNDEAD:
  521.         case OEMERALD:        case OCHEST:        case OCOOKIE:
  522.         case OSAPPHIRE:        case ONOTHEFT:        show1(index,(char **)0);  break;
  523.  
  524.         default:        lprintf("\n%c)   %s",index+'a',objectname[iven[index]]);
  525.                         if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]);
  526.                         else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]);
  527.                         break;
  528.         }
  529.     if (c[WIELD]==index) lprcat(" (weapon in hand)");
  530.     if ((c[WEAR]==index) || (c[SHIELD]==index))  lprcat(" (being worn)");
  531.     if (++srcount>=22) { srcount=0; more(); clear(); }
  532.     }
  533.  
  534. /*
  535.     subroutine to randomly create monsters if needed
  536.  */
  537. randmonst()
  538.     {
  539.     if (c[TIMESTOP]) return;    /*    don't make monsters if time is stopped    */
  540.     if (--rmst <= 0)
  541.         {
  542.         rmst = 120 - (level<<2);  fillmonst(makemonst(level));
  543.         }
  544.     }
  545.  
  546.  
  547. /*
  548.     parse()
  549.  
  550.     get and execute a command
  551.  */
  552. parse()
  553.     {
  554.     register int i,j,k,flag;
  555.     while    (1)
  556.         {
  557.         k = yylex();
  558.         switch(k)    /*    get the token from the input and switch on it    */
  559.             {
  560.             case 'h':    moveplayer(4);    return;        /*    west        */
  561.             case 'H':    run(4);            return;        /*    west        */
  562.             case 'l':    moveplayer(2);    return;        /*    east        */
  563.             case 'L':    run(2);            return;        /*    east        */
  564.             case 'j':    moveplayer(1);    return;        /*    south        */
  565.             case 'J':    run(1);            return;        /*    south        */
  566.             case 'k':    moveplayer(3);    return;        /*    north        */
  567.             case 'K':    run(3);            return;        /*    north        */
  568.             case 'u':    moveplayer(5);    return;        /*    northeast    */
  569.             case 'U':    run(5);            return;        /*    northeast    */
  570.             case 'y':    moveplayer(6);  return;        /*    northwest    */
  571.             case 'Y':    run(6);            return;        /*    northwest    */
  572.             case 'n':    moveplayer(7);    return;        /*    southeast    */
  573.             case 'N':    run(7);            return;        /*    southeast    */
  574.             case 'b':    moveplayer(8);    return;        /*    southwest    */
  575.             case 'B':    run(8);            return;        /*    southwest    */
  576.  
  577.             case '.':    if (yrepcount) viewflag=1; return;        /*    stay here        */
  578.  
  579.             case 'w':    yrepcount=0;    wield();    return;        /*    wield a weapon */
  580.  
  581.             case 'W':    yrepcount=0;    wear();        return;    /*    wear armor    */
  582.  
  583.             case 'r':    yrepcount=0;
  584.                         if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else
  585.                         if (c[TIMESTOP]==0) readscr(); return;        /*    to read a scroll    */
  586.  
  587.             case 'q':    yrepcount=0;    if (c[TIMESTOP]==0) quaff();    return;    /*    quaff a potion        */
  588.  
  589.             case 'd':    yrepcount=0;    if (c[TIMESTOP]==0) dropobj(); return;    /*    to drop an object    */
  590.  
  591.             case 'c':    yrepcount=0;    cast();        return;        /*    cast a spell    */
  592.  
  593.             case 'i':    yrepcount=0;    nomove=1;  showstr();    return;        /*    status        */
  594.  
  595.             case 'e':    yrepcount=0;
  596.                         if (c[TIMESTOP]==0) eatcookie(); return;    /*    to eat a fortune cookie */
  597.  
  598.             case 'D':    yrepcount=0;    seemagic(0);    nomove=1; return;    /*    list spells and scrolls */
  599.  
  600.             case '?':    yrepcount=0;    help(); nomove=1; return;    /*    give the help screen*/
  601.  
  602.             case 'S':    clear();  lprcat("Saving . . ."); lflush();  
  603.                         savegame(savefilename); wizard=1; died(-257);    /*    save the game - doesn't return    */
  604.  
  605.             case 'Z':    yrepcount=0;    if (c[LEVEL]>9) { oteleport(1); return; }
  606.                         cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation");
  607.                         return;    /*    teleport yourself    */
  608.  
  609.             case '^':    /* identify traps */  flag=yrepcount=0;  cursors();
  610.                         lprc('\n');  for (j=playery-1; j<playery+2; j++)
  611.                             {
  612.                             if (j < 0) j=0;        if (j >= MAXY) break;
  613.                             for (i=playerx-1; i<playerx+2; i++)
  614.                                 {
  615.                                 if (i < 0) i=0;    if (i >= MAXX) break;
  616.                                 switch(item[i][j])
  617.                                     {
  618.                                     case OTRAPDOOR:        case ODARTRAP:
  619.                                     case OTRAPARROW:    case OTELEPORTER:
  620.                                         lprcat("\nIts "); lprcat(objectname[item[i][j]]);  flag++;
  621.                                     };
  622.                                 }
  623.                             }
  624.                         if (flag==0) lprcat("\nNo traps are visible");
  625.                         return;
  626.  
  627. #if WIZID
  628.             case '_':    /*    this is the fudge player password for wizard mode*/
  629.                         yrepcount=0;    cursors(); nomove=1;
  630.                         if (userid!=wisid)
  631.                             {
  632.                             lprcat("Sorry, you are not empowered to be a wizard.\n");
  633.                             scbr(); /* system("stty -echo cbreak"); */
  634.                             lflush();  return;
  635.                             }
  636.                         if (getpassword()==0)
  637.                             {
  638.                             scbr(); /* system("stty -echo cbreak"); */ return;
  639.                             }
  640.                         wizard=1;  scbr(); /* system("stty -echo cbreak"); */
  641.                         for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
  642.                         take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
  643.                         c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
  644.                         raiseexperience(6000000L);  c[AWARENESS] += 25000;
  645.                         {
  646.                         register int i,j;
  647.                         for (i=0; i<MAXY; i++)
  648.                             for (j=0; j<MAXX; j++)  know[j][i]=1;
  649.                         for (i=0; i<SPNUM; i++)    spelknow[i]=1;
  650.                         for (i=0; i<MAXSCROLL; i++)  scrollname[i][0]=' ';
  651.                         for (i=0; i<MAXPOTION; i++)  potionname[i][0]=' ';
  652.                         }
  653.                         for (i=0; i<MAXSCROLL; i++)
  654.                           if (strlen(scrollname[i])>2) /* no null items */
  655.                             { item[i][0]=OSCROLL; iarg[i][0]=i; }
  656.                         for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
  657.                           if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
  658.                             { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
  659.                         for (i=1; i<MAXY; i++)
  660.                             { item[0][i]=i; iarg[0][i]=0; }
  661.                         for (i=MAXY; i<MAXY+MAXX; i++)
  662.                             { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
  663.                         for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
  664.                             { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
  665.                         c[GOLD]+=250000;    drawscreen();    return;
  666. #endif
  667.  
  668.             case 'T':    yrepcount=0;    cursors();  if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
  669.                                         if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
  670.                         else lprcat("\nYou aren't wearing anything");
  671.                         return;
  672.  
  673.             case 'g':    cursors();
  674.                         lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
  675.             case ' ':    yrepcount=0;    nomove=1;  return;
  676.  
  677.             case 'v':    yrepcount=0;    cursors();
  678.                         lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
  679.                         if (wizard) lprcat(" Wizard"); nomove=1;
  680.                         if (cheat) lprcat(" Cheater");
  681.                         lprcat(copyright);
  682.                         return;
  683.  
  684.             case 'Q':    yrepcount=0;    quit(); nomove=1;    return;    /*    quit        */
  685.  
  686.             case 'L'-64:  yrepcount=0;    drawscreen();  nomove=1; return;    /*    look        */
  687.  
  688. #if WIZID
  689. #ifdef EXTRA
  690.             case 'A':    yrepcount=0;    nomove=1; if (wizard) { diag(); return; }  /*    create diagnostic file */
  691.                         return;
  692. #endif
  693. #endif
  694.             case 'P':    cursors(); 
  695.                         if (outstanding_taxes>0)
  696.                             lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
  697.                         else
  698.                             lprcat("\nYou do not owe any taxes.");
  699.                         return;
  700.             };
  701.         }
  702.     }
  703.  
  704. parse2()
  705.     {
  706.     if (c[HASTEMONST]) movemonst(); movemonst(); /*    move the monsters        */
  707.     randmonst();    regen();
  708.     }
  709.  
  710. run(dir)
  711.     int dir;
  712.     {
  713.     register int i;
  714.     i=1; while (i)
  715.         {
  716.         i=moveplayer(dir);
  717.         if (i>0) {  if (c[HASTEMONST]) movemonst();  movemonst(); randmonst(); regen(); }
  718.         if (hitflag) i=0;
  719.         if (i!=0)  showcell(playerx,playery);
  720.         }
  721.     }
  722.  
  723. /*
  724.     function to wield a weapon
  725.  */
  726. wield()    
  727.     {
  728.     register int i;
  729.     while (1)
  730.         {
  731.         if ((i = whatitem("wield"))=='\33')  return;
  732.         if (i != '.')
  733.             {
  734.             if (i=='*') showwield();
  735.             else  if (iven[i-'a']==0) { ydhi(i); return; }
  736.             else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
  737.             else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
  738.             else  if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
  739.             else  { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0;  bottomline(); return; }
  740.             }
  741.         }
  742.     }
  743.  
  744. /*
  745.     common routine to say you don't have an item
  746.  */
  747. ydhi(x)
  748.     int x;
  749.     { cursors();  lprintf("\nYou don't have item %c!",x); }
  750. ycwi(x)
  751.     int x;
  752.     { cursors();  lprintf("\nYou can't wield item %c!",x); }
  753.  
  754. /*
  755.     function to wear armor
  756.  */
  757. wear()
  758.     {
  759.     register int i;
  760.     while (1)
  761.         {
  762.         if ((i = whatitem("wear"))=='\33')  return;
  763.         if (i != '.')
  764.             {
  765.             if (i=='*') showwear(); else
  766.             switch(iven[i-'a'])
  767.                 {
  768.                 case 0:  ydhi(i); return;
  769.                 case OLEATHER:  case OCHAIN:  case OPLATE:    case OSTUDLEATHER:
  770.                 case ORING:        case OSPLINT:    case OPLATEARMOR:    case OSSPLATE:
  771.                         if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
  772.                             c[WEAR]=i-'a';  bottomline(); return;
  773.                 case OSHIELD:    if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
  774.                                 if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
  775.                                 c[SHIELD] = i-'a';  bottomline(); return;
  776.                 default:    lprcat("\nYou can't wear that!");
  777.                 };
  778.             }
  779.         }
  780.     }
  781.  
  782. /*
  783.     function to drop an object
  784.  */
  785. dropobj()
  786.     {
  787.     register int i;
  788.     register char *p;
  789.     long amt;
  790.     p = &item[playerx][playery];
  791.     while (1)
  792.         {
  793.         if ((i = whatitem("drop"))=='\33')  return;
  794.         if (i=='*') showstr(); else 
  795.             {
  796.             if (i=='.')    /* drop some gold */
  797.                 {
  798.                 if (*p) { lprcat("\nThere's something here already!"); return; }
  799.                 lprcat("\n\n");
  800.                 cl_dn(1,23);
  801.                 lprcat("How much gold do you drop? ");
  802.                 if ((amt=readnum((long)c[GOLD])) == 0) return;
  803.                 if (amt>c[GOLD])
  804.                     { lprcat("\nYou don't have that much!"); return; }
  805.                 if (amt<=32767)
  806.                     { *p=OGOLDPILE; i=amt; }
  807.                 else if (amt<=327670L)
  808.                     { *p=ODGOLD; i=amt/10; amt = 10*i; }
  809.                 else if (amt<=3276700L)
  810.                     { *p=OMAXGOLD; i=amt/100; amt = 100*i; }
  811.                 else if (amt<=32767000L)
  812.                     { *p=OKGOLD; i=amt/1000; amt = 1000*i; }
  813.                 else
  814.                     { *p=OKGOLD; i=32767; amt = 32767000L; }
  815.                 c[GOLD] -= amt; 
  816.                 lprintf("You drop %d gold pieces",(long)amt);
  817.                 iarg[playerx][playery]=i; bottomgold();
  818.                 know[playerx][playery]=0; dropflag=1;  return;
  819.                 }
  820.             drop_object(i-'a');
  821.             return;
  822.             }
  823.         }
  824.     }
  825.  
  826. /*
  827.  *    readscr()        Subroutine to read a scroll one is carrying
  828.  */
  829. readscr()
  830.     {
  831.     register int i;
  832.     while (1)
  833.         {
  834.         if ((i = whatitem("read"))=='\33')  return;
  835.         if (i != '.')
  836.             {
  837.             if (i=='*') showread(); else
  838.                 {
  839.                 if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
  840.                 if (iven[i-'a']==OBOOK)   { readbook(ivenarg[i-'a']);  iven[i-'a']=0; return; }
  841.                 if (iven[i-'a']==0) { ydhi(i); return; }
  842.                 lprcat("\nThere's nothing on it to read");  return;
  843.                 }
  844.             }
  845.         }
  846.     }
  847.  
  848. /*
  849.  *    subroutine to eat a cookie one is carrying
  850.  */
  851. eatcookie()
  852. {
  853. register int i;
  854. char *p;
  855. while (1)
  856.     {
  857.     if ((i = whatitem("eat"))=='\33')  return;
  858.     if (i != '.')
  859.         if (i=='*') showeat(); else
  860.             {
  861.             if (iven[i-'a']==OCOOKIE)
  862.                 {
  863.                 lprcat("\nThe cookie was delicious.");
  864.                 iven[i-'a']=0;
  865.                 if (!c[BLINDCOUNT])
  866.                     {
  867.                     if (p=fortune(fortfile))
  868.                         {
  869.                         lprcat("  Inside you find a scrap of paper that says:\n");
  870.                         lprcat(p);
  871.                         }
  872.                     }
  873.                 return;
  874.                 }
  875.             if (iven[i-'a']==0) { ydhi(i); return; }
  876.             lprcat("\nYou can't eat that!");  return;
  877.             }
  878.     }
  879. }
  880.  
  881. /*
  882.  *    subroutine to quaff a potion one is carrying
  883.  */
  884. quaff()
  885.     {
  886.     register int i;
  887.     while (1)
  888.         {
  889.         if ((i = whatitem("quaff"))=='\33')  return;
  890.         if (i != '.')
  891.             {
  892.             if (i=='*') showquaff(); else
  893.                 {
  894.                 if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; }
  895.                 if (iven[i-'a']==0) { ydhi(i); return; }
  896.                 lprcat("\nYou wouldn't want to quaff that, would you? ");  return;
  897.                 }
  898.             }
  899.         }
  900.     }
  901.  
  902. /*
  903.     function to ask what player wants to do
  904.  */
  905. whatitem(str)
  906.     char *str;
  907.     {
  908.     int i;
  909.     cursors();  lprintf("\nWhat do you want to %s [* for all] ? ",str);
  910.     i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
  911.     if (i=='\33')  lprcat(" aborted");
  912.     return(i);
  913.     }
  914.  
  915. /*
  916.     subroutine to get a number from the player
  917.     and allow * to mean return amt, else return the number entered
  918.  */
  919. unsigned long readnum(mx)
  920.     long mx;
  921.     {
  922.     register int i;
  923.     register unsigned long amt=0;
  924.     sncbr();
  925.     if ((i=getchar()) == '*')  amt = mx;   /* allow him to say * for all gold */
  926.     else
  927.         while (i != '\n')
  928.             {
  929.             if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
  930.             if ((i <= '9') && (i >= '0') && (amt<999999999))
  931.                 amt = amt*10+i-'0';
  932.             i = getchar();
  933.             }
  934.     scbr();  return(amt);
  935.     }
  936.  
  937. #ifdef HIDEBYLINK
  938. /*
  939.  *    routine to zero every byte in a string
  940.  */
  941. szero(str)
  942.     register char *str;
  943.     {
  944.     while (*str)
  945.         *str++ = 0;
  946.     }
  947. #endif HIDEBYLINK
  948.  
  949. #ifdef TIMECHECK
  950. /*
  951.  *    routine to check the time of day and return 1 if its during work hours
  952.  *    checks the file ".holidays" for forms like "mmm dd comment..."
  953.  */
  954. int playable()
  955.     {
  956.     long g_time,time();
  957.     int hour,day,year;
  958.     char *date,*month,*p;
  959.  
  960.     time(&g_time);    /* get the time and date */
  961.     date = ctime(&g_time); /* format: Fri Jul  4 00:27:56 EDT 1986 */
  962.     year = atoi(date+20);
  963.     hour = (date[11]-'0')*10 + date[12]-'0';
  964.     day  = (date[8]!=' ') ? ((date[8]-'0')*10 + date[9]-'0') : (date[9]-'0');
  965.     month = date+4;  date[7]=0;    /* point to and NULL terminate month */
  966.  
  967.     if (((hour>=8 && hour<17)) /* 8AM - 5PM */
  968.         && strncmp("Sat",date,3)!=0     /* not a Saturday */
  969.         && strncmp("Sun",date,3)!=0)    /* not a Sunday */
  970.             {
  971.         /* now check for a .holidays datafile */
  972.             lflush();
  973.             if (lopen(holifile) >= 0)
  974.                 for ( ; ; )
  975.                     {
  976.                     if ((p=lgetw())==0) break;
  977.                     if (strlen(p)<6) continue;
  978.                     if ((strncmp(p,month,3)==0) && (day==atoi(p+4)) && (year==atoi(p+7)))
  979.                         return(0); /* a holiday */
  980.                     }
  981.             lrclose();  lcreat((char*)0);
  982.             return(1);
  983.             }
  984.     return(0);
  985.     }
  986. #endif TIMECHECK
  987.